import { authMenuList } from '@/apis/auth/menu'
import useMessageApi from '@/hooks/useMessageApi'
import { EXCEPTION_ROUTE } from '@/router/base'
import {
    IAuthMenu,
    IAuthMenuPinia,
    IAuthMenuRoute,
    IAuthMenuTreeNode,
    IAuthMenuEditTreeNode
} from '@/types/auth/menu'
import { defineStore } from 'pinia'
import { h } from 'vue'
import { RouterLink } from 'vue-router'

const { setMessage } = useMessageApi()

export const useAuthMenuStore = defineStore('menu', {
    state: (): IAuthMenuPinia => ({
        inited: false,
        source: [],
        routes: [],
        menuTree: [],
        firstRoute: undefined,
        canExpandKeys: [],
        editTree: []
    }),
    getters: {
        getSourceItem: (state) => {
            return (menuId: IAuthMenu['id']) =>
                state.source.find((item) => item.id === menuId)
        }
    },
    actions: {
        async init() {
            setMessage({
                content: '初始化菜单...'
            })

            try {
                const source = await authMenuList()
                this.source = source

                const { routes, menuTree, canExpandKeys, editTree } =
                    handleSource(source)
                this.menuTree = menuTree
                this.routes = routes
                this.canExpandKeys = canExpandKeys
                this.editTree = editTree

                if (routes.length) {
                    this.firstRoute = routes[0]
                }

                this.inited = true
                setMessage()
                return true
            } catch (error) {
                setMessage({
                    content: (error as Error).message,
                    type: 'error'
                })

                return Promise.reject(error)
            }
        }
    }
})

function handleSource(menus: IAuthMenu[]) {
    // 菜单
    const menuMap: { [id: number]: IAuthMenuTreeNode } = {}

    // 编辑菜单
    const editMap: { [id: IAuthMenu['id']]: IAuthMenuEditTreeNode } = {}

    // 可以展开的菜单
    const canExpandKeys: IAuthMenu['id'][] = []

    // 路由
    const routes: IAuthMenuRoute[] = []
    const allModules = {
        ...import.meta.glob('/src/views/**/*.vue')
    }

    // 一次循环
    menus.forEach((item) => {
        // 获取路径
        const paths = [item.path]
        let temp: IAuthMenu | undefined = item
        while (temp?.pid) {
            const finded = menus.find((i) => i.id === temp?.pid)
            if (finded) {
                paths.push(finded.path)
            }

            temp = finded
        }
        paths.reverse()

        // 菜单映射
        menuMap[item.id] = {
            id: item.id,
            pid: item.pid,
            nodeTitle: item.title,

            key: paths.join('-'),
            icon: undefined,
            show: !item.hidden,
            label: item.component
                ? () =>
                      h(
                          RouterLink,
                          {
                              to: {
                                  name: paths.join('-')
                              }
                          },
                          { default: () => item.title }
                      )
                : item.title
        }

        // 编辑菜单
        editMap[item.id] = {
            ...item,
            disabled: !!item._protect
        }

        // 路由
        let component: (() => Promise<unknown>) | null = null
        if (`/src/views${item.component}` in allModules) {
            component = allModules[`/src/views${item.component}`]
        }
        const newItem: IAuthMenuRoute = {
            name: paths.join('-'),
            path: `/${paths.join('/')}`,
            component: component || EXCEPTION_ROUTE.component,
            meta: {
                pid: item.pid,
                title: item.title,
                icon: item.icon,
                sort: item.sort,
                hidden: item.hidden,
                ignoreCache: item.ignore_cache,
                active: item.active
            },
            children: []
        }

        routes.push(newItem)
    })

    // 二次循环
    const menuTree: IAuthMenuTreeNode[] = []
    const editTree: IAuthMenuEditTreeNode[] = []
    menus.forEach((item: IAuthMenu) => {
        // 菜单
        const node = menuMap[item.id]
        if (node && node.show) {
            if (!node.pid) {
                menuTree.push(node)
            } else {
                const parentNode = menuMap[node.pid]
                if (parentNode) {
                    if (!parentNode.children) {
                        parentNode.children = []
                    }
                    parentNode.children.push(node)
                }
            }
        }

        // 编辑
        const editNode = editMap[item.id]
        if (!editNode.pid) {
            editTree.push(editNode)
        } else {
            const parentNode = editMap[editNode.pid]

            if (parentNode) {
                if (!canExpandKeys.includes(parentNode.id)) {
                    canExpandKeys.push(parentNode.id)
                }

                if (!parentNode.children) {
                    parentNode.children = []
                }
                parentNode.children.push(editNode)
            }
        }
    })

    return { menuTree, routes, canExpandKeys, editTree }
}
